package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.StageLogEntity;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.service.stage.StageHandle;
import com.xbongbong.paas.service.stage.StageHandleFactory;
import com.xbongbong.paas.service.stage.StageLogHandle;
import com.xbongbong.paas.service.stage.StageLogHandleFactory;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.opportunity.pojo.JudgeStageChangedPojo;
import com.xbongbong.pro.opportunity.pojo.StageLogSavePojo;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.OpportunityStageLogEntity;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Component
public class StageLogHelp {

    @Resource
    private StageHandleFactory stageHandleFactory;
    @Resource
    private StageLogHandleFactory stageLogHandleFactory;

    /**
     * 新建或编辑数据的时候判断阶段是否发生了阶段变更
     *
     * @param corpid
     * @param formId
     * @param dataId
     * @param stageCode 目标阶段code
     * @return JudgeStageChangedPojo
     */
    public JudgeStageChangedPojo judgeStageChanged(String corpid, Long formId, Long dataId, String stageCode, Integer saasMark, Integer businessType) {
        StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
        StageLogHandle stageLogHandle = stageLogHandleFactory.getStageLogHandle(saasMark, businessType);
        // 获取目标阶段
        PaasStageEntity targetStage = null;
        if (StringUtil.isNotEmpty(stageCode)) {
            targetStage = stageHandle.getByCode(corpid, formId, stageCode);
        }
        // 获取当前阶段
        PaasStageEntity sourceStage = null;
        StageLogEntity sourceStageLog = stageLogHandle.getNowStageLog(dataId, corpid, formId);
        if (Objects.nonNull(sourceStageLog)) {
            sourceStage = stageHandle.getByCode(corpid, formId, sourceStageLog.getStageCode());
        }
        // 新建或编辑数据的时候发生了阶段变更【从没有阶段到有阶段】
        boolean isAddSelectStage = Objects.isNull(sourceStage) && Objects.nonNull(targetStage);
        // 编辑数据的时候发生了阶段变更【从一个阶段变更为了另一个阶段】
        boolean isEditSelectStage = Objects.nonNull(sourceStage) && Objects.nonNull(targetStage) && !Objects.equals(sourceStage.getCode(), targetStage.getCode());
        String targetStageName = Objects.isNull(targetStage) ? "" : targetStage.getName();
        String sourceStageName = Objects.isNull(sourceStage) ? "" : sourceStage.getName();
        boolean isStageChanged = isAddSelectStage || isEditSelectStage;
        return new JudgeStageChangedPojo(targetStage, sourceStage, targetStageName, sourceStageName, isStageChanged, sourceStageLog);
    }

    /**
     * 新建或编辑数据的时候如果阶段发生了变更则保存相关或更新相关的阶段记录
     *
     * @param stageLogSavePojo
     */
    public void saveStageLog(StageLogSavePojo stageLogSavePojo, Integer saasMark, Integer businessType) {
        StageLogHandle stageLogHandle = stageLogHandleFactory.getStageLogHandle(saasMark, businessType);
        JudgeStageChangedPojo judgeStageChangedPojo = stageLogSavePojo.getJudgeStageChangedPojo();
        if (!judgeStageChangedPojo.getIsStageChanged()) {
            return;
        }
        Long currentTime = DateTimeUtil.getInt();
        PaasStageEntity targetStage = judgeStageChangedPojo.getTargetStage();
        PaasStageEntity sourceStage = judgeStageChangedPojo.getSourceStage();

        // 获取目标阶段是否已有阶段记录，如果已经有阶段记录则更新，否则新建阶段记录
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("dataId", stageLogSavePojo.getDataId());
        param.put("corpid", stageLogSavePojo.getCorpid());
        param.put("formId", stageLogSavePojo.getFormId());
        param.put("stageCode", targetStage.getCode());
        param.put("del", 0);
        List<StageLogEntity> saleStageLogList = stageLogHandle.findEntitys(param);
        StageLogEntity targetStageLog;
        if (saleStageLogList.isEmpty()) {
            targetStageLog = new OpportunityStageLogEntity();
            targetStageLog.setCorpid(stageLogSavePojo.getCorpid());
            targetStageLog.setFormId(stageLogSavePojo.getFormId());
            targetStageLog.setStageProcessId(targetStage.getStageProcessId());
            targetStageLog.setStageId(targetStage.getId());
            targetStageLog.setStageType(targetStage.getType());
            targetStageLog.setStageCode(targetStage.getCode());
            targetStageLog.setDataId(stageLogSavePojo.getDataId());
            targetStageLog.setAddTime(currentTime);
            targetStageLog.setHistoryStayTime(0L);
        } else {
            targetStageLog = saleStageLogList.get(0);
            targetStageLog.setLastIntoTime(targetStageLog.getIntoTime());
        }
        targetStageLog.setIsNow(1);
        targetStageLog.setReasonId(stageLogSavePojo.getReasonId());
        targetStageLog.setMemo(stageLogSavePojo.getWastageMemo());
        targetStageLog.setUpdateTime(currentTime);
        targetStageLog.setDel(0);
        targetStageLog.setIntoTime(currentTime);
        targetStageLog.setOutTime(0L);
        // 如果是进入流失阶段，则记录流失之前的阶段
        if (Objects.nonNull(sourceStage) && Objects.equals(targetStage.getType(), StageTypeEnum.FAIL_STAGE.getType())) {
            targetStageLog.setBeforeStageCode(sourceStage.getCode());
            targetStageLog.setPreStageId(sourceStage.getId());
        }
        stageLogHandle.save(targetStageLog);

        // 更新来源阶段的阶段记录
        StageLogEntity sourceStageLog = judgeStageChangedPojo.getSourceStageLog();
        if (Objects.nonNull(sourceStageLog)) {
            sourceStageLog.setIsNow(0);
            sourceStageLog.setOutTime(currentTime);
            long historyStayTime = Objects.isNull(sourceStageLog.getHistoryStayTime()) ? 0L : sourceStageLog.getHistoryStayTime();
            historyStayTime = historyStayTime + sourceStageLog.getOutTime() - sourceStageLog.getIntoTime();
            sourceStageLog.setHistoryStayTime(historyStayTime);
            sourceStageLog.setUpdateTime(currentTime);
            stageLogHandle.save(sourceStageLog);
        }
    }

    public void insertBatchStageLogList(List<StageLogEntity> stageLogList, Integer saasMark, Integer businessType) {
        StageLogHandle stageLogHandle = stageLogHandleFactory.getStageLogHandle(saasMark, businessType);
        stageLogHandle.insertBatchStageLogList(stageLogList);
    }

    public Integer deleteByStageProcessIdAndDataIdIn(List<Long> dataIdIn, String corpid, Long formId, Long stageProcessId, Long stageId, Integer saasMark, Integer businessType) {
        StageLogHandle stageLogHandle = stageLogHandleFactory.getStageLogHandle(saasMark, businessType);
        return stageLogHandle.deleteByStageProcessIdAndDataIdIn(dataIdIn, corpid, formId, stageProcessId, stageId);
    }

    public void formatProductForProcess(List<ContractProductEntity> productList, JSONObject newData) {
        JSONArray jsonArray = new JSONArray();
        newData.put(ContractEnum.PRODUCT.getAttr(), jsonArray);
        for (ContractProductEntity contractProductEntity : productList) {
            JSONObject productObject = new JSONObject();
            if (Objects.nonNull(contractProductEntity.getData())) {
                productObject = contractProductEntity.getData();
            }
            productObject.put(BusinessConstant.PRODUCT_SUB_ID, contractProductEntity.getId());
            productObject.put(ContractProductEnum.PRODUCT.getAttr(), contractProductEntity.getProductId());
            productObject.put(ContractProductEnum.UNIT.getAttr(), contractProductEntity.getProductUnit());
            productObject.put(ContractProductEnum.NUM.getAttr(), contractProductEntity.getProductNum());
            productObject.put(ContractProductEnum.PRICE.getAttr(), contractProductEntity.getCost());
            productObject.put(ContractProductEnum.DISCOUNT.getAttr(), contractProductEntity.getDiscount());
            productObject.put(ContractProductEnum.SELLING_PRICE.getAttr(), contractProductEntity.getPrice());
            productObject.put(ContractProductEnum.SUBTOTAL.getAttr(), contractProductEntity.getSumPrice());
            productObject.put(ContractProductEnum.MEMO.getAttr(), contractProductEntity.getMemo());
            productObject.put(ContractProductEnum.OUTSTOCK_NUM.getAttr(), contractProductEntity.getOutstockNum());
            productObject.put(ContractProductEnum.WAIT_OUTSTOCK_NUM.getAttr(), contractProductEntity.getWaitOutStockNum());
            // productObject.put(ContractProductEnum.RETURN_NUM.getAttr(), contractProductEntity.getMemo());
            // productObject.put(ContractProductEnum.STOCK.getAttr(), contractProductEntity.getMemo());
            // productObject.put(ContractProductEnum.OUT_OF_STOCK.getAttr(), contractProductEntity.getMemo());
            // productObject.put(ContractProductEnum.CONTRACT_STATUS.getAttr(), contractProductEntity.getMemo());
            productObject.put(ContractProductEnum.SHIPMENTS_NUM.getAttr(), contractProductEntity.getShipmentsNum());
            // productObject.put(ContractProductEnum.PROMOTION.getAttr(), contractProductEntity.getMemo());
            productObject.put(ContractProductEnum.STATUS.getAttr(), contractProductEntity.getStatus());
            productObject.put(ContractProductEnum.PURCHASE_NUM.getAttr(), contractProductEntity.getPurchaseNum());
            jsonArray.add(productObject);
        }
    }
}
